#include "Functions.fxh"
#include "vertex_types.fxh"
#include "Samplers.fxh"
//#include "globals.fxh"

float4 g_AmbientLightColor = {0.2, 0.2, 0.2, 1.0};

struct TMultiRenderTargetPixel
{
	float4 RT0 : COLOR0; //Albedo (float3) + (float) SpecularFactor
	float4 RT1 : COLOR1; //AmbientLight (float3) + (float) SpecularPow
	float4 RT2 : COLOR2; //Normal (float3) + (float) Not used
	float4 RT3 : COLOR3; //Depth (float4)
};
//*****************************************************************************************
TNORMAL_TEXTURED_VERTEX_PS NormalTexturedVertexRenderVS(TNORMAL_TEXTURED_VERTEX_VS IN)
{
	TNORMAL_TEXTURED_VERTEX_PS OUT =  (TNORMAL_TEXTURED_VERTEX_PS) 0;
	OUT.WorldNormal = mul(IN.Normal,(float3x3)g_WorldMatrix);
	OUT.UV = IN.UV.xy;
	OUT.WorldPosition=mul(float4(IN.Position,1.0),g_WorldViewProjectionMatrix);
	OUT.HPosition=OUT.WorldPosition;
	return OUT;
}

TMultiRenderTargetPixel NormalTexturedVertexRenderPS(TNORMAL_TEXTURED_VERTEX_PS IN)
{
	TMultiRenderTargetPixel OUT=(TMultiRenderTargetPixel) 0;
	float4 l_DiffuseColor=tex2D(S0LinearSampler,IN.UV);

	if(l_DiffuseColor.a<1.0)
		clip(-1);	
	
	OUT.RT0.xyz=l_DiffuseColor.xyz;
	OUT.RT1.xyz=l_DiffuseColor.xyz*g_AmbientLightColor.xyz;
	OUT.RT2.xyz=Normal2Texture(normalize(IN.WorldNormal));
	OUT.RT3=IN.WorldPosition.z/IN.WorldPosition.w;
	//return 
	return OUT;
}

technique GBufferNormalTexturedVertexTechnique
{
	pass p0
	{
		VertexShader = compile vs_3_0 NormalTexturedVertexRenderVS();
		PixelShader = compile ps_3_0 NormalTexturedVertexRenderPS();
	}
}
//***********************************************************************************************

TNORMAL_COLORED_VERTEX_PS  NormalColoredVertexRenderVS(TNORMAL_COLORED_VERTEX_VS  IN)
{
	TNORMAL_COLORED_VERTEX_PS OUT =  (TNORMAL_COLORED_VERTEX_PS) 0;
	OUT.WorldNormal = mul(IN.Normal,(float3x3)g_WorldMatrix);
	OUT.Color=IN.Color;
	OUT.WorldPosition=mul(float4(IN.Position,1.0),g_WorldViewProjectionMatrix);
	OUT.HPosition=OUT.WorldPosition;
	return OUT;
}

TMultiRenderTargetPixel NormalColoredVertexRenderPS(TNORMAL_COLORED_VERTEX_PS IN)
{
	TMultiRenderTargetPixel OUT=(TMultiRenderTargetPixel) 0;
	float4 l_DiffuseColor=IN.Color;

	if(l_DiffuseColor.a<0.999)
		clip(-1);	
	
	OUT.RT0.xyz=l_DiffuseColor.xyz;
	OUT.RT1.xyz=l_DiffuseColor.xyz*g_AmbientLightColor.xyz;
	OUT.RT2.xyz=Normal2Texture(normalize(IN.WorldNormal));
	OUT.RT3=IN.WorldPosition.z/IN.WorldPosition.w;
	//return 
	return OUT;
}

technique GBufferNormalColoredVertexTechnique
{
	pass p0
	{
		VertexShader = compile vs_3_0 NormalColoredVertexRenderVS();
		PixelShader = compile ps_3_0 NormalColoredVertexRenderPS();
	}
}
//****************************************************************************

TNORMAL_2TEXTURED_VERTEX_PS  Normal2TexturedVertexRenderVS(TNORMAL_2TEXTURED_VERTEX_VS  IN)
{
	TNORMAL_2TEXTURED_VERTEX_PS OUT =  (TNORMAL_2TEXTURED_VERTEX_PS) 0;
	OUT.WorldNormal = mul(IN.Normal,(float3x3)g_WorldMatrix);
	OUT.UV = IN.UV;
	OUT.UV2 = IN.UV2;
	OUT.WorldPosition=mul(float4(IN.Position,1.0),g_WorldViewProjectionMatrix);
	OUT.HPosition=OUT.WorldPosition;
	return OUT;
}


TMultiRenderTargetPixel Normal2TexturedVertexRenderPS(TNORMAL_2TEXTURED_VERTEX_PS IN)
{
	TMultiRenderTargetPixel OUT=(TMultiRenderTargetPixel) 0;
	float4 l_DiffuseColor=tex2D(S0LinearSampler,IN.UV)*tex2D(S1LinearSampler,IN.UV2);

	if(l_DiffuseColor.a<1.0)
		clip(-1);	
	
	OUT.RT0.xyz=l_DiffuseColor.xyz;
	OUT.RT1.xyz=l_DiffuseColor.xyz*g_AmbientLightColor.xyz;
	OUT.RT2.xyz=Normal2Texture(normalize(IN.WorldNormal));
	OUT.RT3=IN.WorldPosition.z/IN.WorldPosition.w;
	//return 
	return OUT;
}

technique GBufferNormal2TexturedVertexTechnique
{
	pass p0
	{

		VertexShader = compile vs_3_0 Normal2TexturedVertexRenderVS();
		PixelShader = compile ps_3_0 Normal2TexturedVertexRenderPS();
	}
}


//****************************************************************************
/*TNORMAL_COLORED_TEXTURED_VERTEX_PS NormalColoredTexturedVertexRenderVS(TNORMAL_COLORED_TEXTURED_VERTEX_VS  IN)
{
	TNORMAL_COLORED_TEXTURED_VERTEX_PS OUT = (TNORMAL_COLORED_TEXTURED_VERTEX_PS) 0;
	
	OUT.WorldNormal = mul(IN.Normal,(float3x3)g_WorldMatrix);
	OUT.UV = IN.UV;
	OUT.WorldPosition=mul(float4(IN.Position,1.0),g_WorldViewProjectionMatrix);
	OUT.HPosition=OUT.WorldPosition;
	OUT.Color=IN.Color;
	return OUT;
}

TMultiRenderTargetPixel NormalColoredTexturedVertexRenderPS(TNORMAL_COLORED_TEXTURED_VERTEX_PS IN)
{
	TMultiRenderTargetPixel OUT = (TMultiRenderTargetPixel) 0;
	
	float4 l_DiffuseColor=float4(IN.Color, 1.0)*tex2D(S0LinearSampler,IN.UV);
	
	if(l_DiffuseColor.a<1.0)
		clip(-1);	
	
	OUT.RT0.xyz=l_DiffuseColor.xyz;
	OUT.RT1.xyz=l_DiffuseColor.xyz*g_AmbientLightColor.xyz;
	OUT.RT2.xyz=Normal2Texture(normalize(IN.WorldNormal));
	OUT.RT3=IN.WorldPosition.z/IN.WorldPosition.w;
	return OUT;
}

technique GBufferNormalColoredTexturedVertexTechnique
{
	pass p0
	{
		VertexShader = compile vs_3_0 NormalColoredTexturedVertexRenderVS();
		PixelShader = compile ps_3_0 NormalColoredTexturedVertexRenderPS();
	}
}
*/

//****************************************************************************
/*TNORMAL_COLORED_2TEXTURED_VERTEX_PS NormalColored2TexturedVertexRenderVS(TNORMAL_COLORED_2TEXTURED_VERTEX_VS IN)
{
	TNORMAL_COLORED_2TEXTURED_VERTEX_PS OUT = (TNORMAL_COLORED_2TEXTURED_VERTEX_PS) 0;
	
	OUT.WorldNormal = mul(IN.Normal,(float3x3)g_WorldMatrix);
	OUT.UV = IN.UV;
	OUT.UV2 = IN.UV2;
	OUT.WorldPosition=mul(float4(IN.Position,1.0),g_WorldViewProjectionMatrix);
	OUT.HPosition=OUT.WorldPosition;
	OUT.Color=IN.Color;
	return OUT;
}

TMultiRenderTargetPixel NormalColored2TexturedVertexRenderPS(TNORMAL_COLORED_2TEXTURED_VERTEX_PS IN)
{
	TMultiRenderTargetPixel OUT = (TMultiRenderTargetPixel) 0;
	
	float4 l_DiffuseColor=float4(IN.Color, 1.0)*tex2D(S0LinearSampler,IN.UV)*tex2D(S0LinearSampler,IN.UV2);
	
	if(l_DiffuseColor.a<1.0)
		clip(-1);	
	
	OUT.RT0.xyz=l_DiffuseColor.xyz;
	OUT.RT1.xyz=l_DiffuseColor.xyz*g_AmbientLightColor.xyz;
	OUT.RT2.xyz=Normal2Texture(normalize(IN.WorldNormal));
	OUT.RT3=IN.WorldPosition.z/IN.WorldPosition.w;
	return OUT;
}

technique GBufferNormalColored2TexturedVertexTechnique
{
	pass p0
	{
		VertexShader = compile vs_3_0 NormalColored2TexturedVertexRenderVS();
		PixelShader = compile ps_3_0 NormalColored2TexturedVertexRenderPS();
	}
}
*/

//****************************************************************************
float g_Bump=0.8;

TNORMAL_TANGENT_BINORMAL_TEXTURED_VERTEX_PS NormalTangentBinormalTexturedVertexRenderVS(TNORMAL_TANGENT_BINORMAL_TEXTURED_VERTEX_VS IN)
{
	TNORMAL_TANGENT_BINORMAL_TEXTURED_VERTEX_PS OUT = (TNORMAL_TANGENT_BINORMAL_TEXTURED_VERTEX_PS) 0;
	
	OUT.WorldNormal = mul(IN.Normal,(float3x3)g_WorldMatrix);
	OUT.UV = IN.UV;
	OUT.WorldPosition=mul(float4(IN.Position,1.0),g_WorldViewProjectionMatrix);
	OUT.HPosition=OUT.WorldPosition;
	OUT.WorldTangent=mul(IN.Tangent.xyz,(float3x3)g_WorldMatrix);
	OUT.WorldBinormal = mul(cross(IN.Tangent.xyz,IN.Normal),(float3x3)g_WorldMatrix);
	
	return OUT;
}

TMultiRenderTargetPixel NormalTangentBinormalTexturedVertexRenderPS(TNORMAL_TANGENT_BINORMAL_TEXTURED_VERTEX_PS IN)
{
	TMultiRenderTargetPixel OUT = (TMultiRenderTargetPixel) 0;
	
	float4 l_DiffuseColor=tex2D(S0LinearSampler,IN.UV);
	
	if(l_DiffuseColor.a<1.0)
		clip(-1);	
	
	OUT.RT0.xyz=l_DiffuseColor.xyz;
	OUT.RT1.xyz=l_DiffuseColor.xyz*g_AmbientLightColor.xyz;
	
	float3 Nn=normalize(IN.WorldNormal);
	float3 Tn=normalize(IN.WorldTangent);
	float3 Bn=normalize(IN.WorldBinormal);
	float3 bump=g_Bump*(tex2D(S1LinearSampler,IN.UV).rgb - float3(0.5,0.5,0.5));
	Nn = Nn + bump.x*Tn + bump.y*Bn;
	Nn = normalize(Nn);
	
	OUT.RT2.xyz=Normal2Texture(Nn);
	OUT.RT3=IN.WorldPosition.z/IN.WorldPosition.w;

	return OUT;
}

technique GBufferNormalTangentBinormalTexturedVertexTechnique
{
	pass p0
	{
		VertexShader = compile vs_3_0 NormalTangentBinormalTexturedVertexRenderVS();
		PixelShader = compile ps_3_0 NormalTangentBinormalTexturedVertexRenderPS();
	}
}


//****************************************************************************
/*
TNORMAL_TANGENT_BINORMAL_2TEXTURED_VERTEX_PS NormalTangentBinormal2TexturedVertexRenderVS(TNORMAL_TANGENT_BINORMAL_2TEXTURED_VERTEX_VS IN)
{
	TNORMAL_TANGENT_BINORMAL_2TEXTURED_VERTEX_PS OUT = (TNORMAL_TANGENT_BINORMAL_2TEXTURED_VERTEX_PS) 0;
	
	OUT.WorldNormal = mul(IN.Normal,(float3x3)g_WorldMatrix);
	OUT.UV = IN.UV;
	OUT.UV2 = IN.UV2;
	OUT.WorldPosition=mul(float4(IN.Position,1.0),g_WorldViewProjectionMatrix);
	OUT.HPosition=OUT.WorldPosition;
	OUT.WorldTangent=mul(IN.Tangent.xyz,(float3x3)g_WorldMatrix);
	OUT.WorldBinormal = mul(cross(IN.Tangent.xyz,IN.Normal),(float3x3)g_WorldMatrix);
	
	return OUT;
}

TMultiRenderTargetPixel NormalTangentBinormal2TexturedVertexRenderPS(TNORMAL_TANGENT_BINORMAL_2TEXTURED_VERTEX_PS IN)
{
	TMultiRenderTargetPixel OUT = (TMultiRenderTargetPixel) 0;
	
	float4 l_DiffuseColor=tex2D(S0LinearSampler,IN.UV)*tex2D(S1LinearSampler,IN.UV2);
	
	if(l_DiffuseColor.a<1.0)
		clip(-1);	
	
	OUT.RT0.xyz=l_DiffuseColor.xyz;
	OUT.RT1.xyz=l_DiffuseColor.xyz*g_AmbientLightColor.xyz;
	
	float3 Nn=normalize(IN.WorldNormal);
	float3 Tn=normalize(IN.WorldTangent);
	float3 Bn=normalize(IN.WorldBinormal);
	float3 bump=g_Bump * ( ( (tex2D(S0LinearSampler,IN.UV)).rgb * (tex2D(S1LinearSampler,IN.UV2)) ).rgb - float3(0.5,0.5,0.5) );
	Nn = Nn + bump.x*Tn + bump.y*Bn;
	Nn = normalize(Nn);
	
	OUT.RT2.xyz=Normal2Texture(Nn);
	OUT.RT3=IN.WorldPosition.z/IN.WorldPosition.w;

	return OUT;
}

technique GBufferNormalTangentBinormal2TexturedVertexTechnique
{
	pass p0
	{
		VertexShader = compile vs_3_0 NormalTangentBinormal2TexturedVertexRenderVS();
		PixelShader = compile ps_3_0 NormalTangentBinormal2TexturedVertexRenderPS();
	}

}*/

//****************************************************************************

CAL3D_HW_VERTEX_PS Cal3DHWRenderVS(CAL3D_HW_VERTEX_VS IN)
{
	CAL3D_HW_VERTEX_PS OUT=(CAL3D_HW_VERTEX_PS)0;
	float3 l_Normal= 0;
	//float3 l_Normal = IN.Normal.xyz;
	float3 l_Tangent=0;
	CalcAnimatedNormalTangent(IN.Normal.xyz, IN.Tangent.xyz, IN.Indices, IN.Weight, l_Normal, l_Tangent);
	float3 l_Position=CalcAnimtedPos(float4(IN.Position.xyz,1.0), IN.Indices, IN.Weight);
	float4 l_WorldPosition=float4(l_Position, 1.0);
	//OUT.WorldPosition=mul(l_WorldPosition,g_WorldMatrix);
	OUT.WorldNormal=normalize(mul(l_Normal,g_WorldMatrix));
	OUT.WorldTangent=normalize(mul(l_Tangent,g_WorldMatrix));
	OUT.WorldBinormal=mul(cross(l_Tangent,l_Normal),(float3x3)g_WorldMatrix);
	OUT.UV = IN.TexCoord.xy;
	OUT.HPosition = mul(l_WorldPosition, g_WorldViewProjectionMatrix );
	OUT.WorldPosition=OUT.HPosition;
	return OUT;
	
	/*
	OUT.WorldPosition=mul(float4(IN.Position,1.0),g_WorldViewProjectionMatrix);
	OUT.HPosition=OUT.WorldPosition;*/
}

TMultiRenderTargetPixel Cal3DHWRenderPS(CAL3D_HW_VERTEX_PS IN)
{
	TMultiRenderTargetPixel OUT = (TMultiRenderTargetPixel) 0;
	
	//float3 Nn=CalcBumpMap(IN.WorldPosition, IN.WorldNormal, IN.WorldTangent, IN.WorldBinormal, IN.UV);
	
	//float3 bump=g_Bump*(tex2D(S1LinearSampler,IN.UV).rgb - float3(0.5,0.5,0.5));
	float3 Nn=normalize(IN.WorldNormal);
	//Nn = Nn + bump.x*IN.WorldTangent + bump.y*IN.WorldBinormal;
	//Nn = normalize(Nn);

	float4 l_DiffuseColor=tex2D(S0LinearSampler, IN.UV);

	OUT.RT0.xyz=l_DiffuseColor.xyz;
	OUT.RT1.xyz=l_DiffuseColor.xyz*g_AmbientLightColor.xyz;
	OUT.RT2.xyz=Normal2Texture(Nn);
	OUT.RT3=IN.WorldPosition.z/IN.WorldPosition.w;
	
	return OUT;
}

technique GBufferCal3DHW
{
	pass p0
	{
		VertexShader = compile vs_3_0 Cal3DHWRenderVS();
		PixelShader = compile ps_3_0 Cal3DHWRenderPS();
	}
}

//****************************************************************************
